home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Topik
/
Topik - Disk 02 - Fonts and CLI Commands (19xx)(Topik Public Domain)(PD)[a][WB].zip
/
Topik - Disk 02 - Fonts and CLI Commands (19xx)(Topik Public Domain)(PD)[a][WB].adf
/
Source
/
memtrace.asm
< prev
next >
Wrap
Assembly Source File
|
1989-04-20
|
10KB
|
291 lines
* =========================== MemTrace ===========================
*
* Monitors calls to AllocMem and FreeMem for tracking down wayward memory.
* Uses two buffers to store the size, address, and requesting task. Each
* buffer area "wraps around" when filled; data may be lost, but no harm
* will be done.
*
* Two commands are accepted from the input stream:
* 'B' ==> prints out the buffer (after switching buffers)
* 'E' ==> exits from the program.
*
* Written by William S. Hawes (1987)
* ========================================================================
SECTION MemTrace,CODE
INCLUDE "exec/types.i"
INCLUDE "exec/nodes.i"
INCLUDE "exec/libraries.i"
* Macro to call a library function (assumes library pointer is in A6)
CALLSYS MACRO * FunctionName
CALLLIB _LVO\1
ENDM
* Macro to define an external library entry point (offset)
XLIB MACRO * FunctionName
XREF _LVO\1
ENDM
XREF _AbsExecBase
XREF _printf
XDEF _DOSBase
XDEF _stdout
XLIB AllocMem
XLIB CloseLibrary
XLIB Disable
XLIB Enable
XLIB FindTask
XLIB FreeMem
XLIB OpenLibrary
XLIB SetFunction
XLIB Input
XLIB Output
XLIB Read
STACKBUF EQU 32
MAXCNT EQU 128 ; maximum number of entries
start: movea.l _AbsExecBase,a6
lea -STACKBUF(sp),sp
lea DOSlib(pc),a1
moveq #0,d0
CALLSYS OpenLibrary
move.l d0,d6
move.l d0,_DOSBase
beq Exit ; error??
; Allocate the buffer areas (before patching the functions!)
move.l #MAXCNT*16,d0 ; MAXCNT 16-byte entries
move.l d0,Save2 ; store offset
add.l d0,d0 ; two buffers ...
move.l #(1<<16)!(1<<0),d1 ; MEMF_PUBLIC!MEMF_CLEAR
CALLSYS AllocMem
move.l d0,Save1 ; first buffer
add.l d0,Save2 ; second buffer
move.l d0,Buffer ; current buffer
beq CloseDOS ; error ...
bsr Zap ; zap the functions ...
; Get the input and output streams
exg d6,a6
CALLSYS Input
move.l d0,d4
CALLSYS Output
move.l d0,_stdout
exg d6,a6
; Wait for a character: 'B' or 'E'
1$: move.l d4,d1 ; input filehandle
move.l sp,d2 ; buffer area
moveq #STACKBUF,d3 ; buffer size
exg d6,a6
CALLSYS Read
exg d6,a6
tst.l d0 ; get one?
beq.s 1$ ; no
move.b (sp),d0 ; the character ...
bclr #5,d0 ; uppercase
subi.b #'B',d0 ; 'Begin'?
beq.s 2$ ; yes
subq.b #'E'-'B',d0 ; 'End'?
beq.s 10$ ; yes
bra.s 1$ ; ignore
; Swap the buffer areas so the one we're printing doesn't get
; overwritten.
2$: movea.l Save1,a0 ; first buffer area
movea.l Save2,a1 ; second buffer area
cmpa.l Buffer,a0 ; using first buffer?
beq.s 4$ ; yes
3$: exg a0,a1 ; no ... swap pointers
4$: clr.l (a1) ; reset count in new buffer
move.l a1,Buffer ; switch buffers
move.l (a0),d2 ; number of entries
lea 16(a0),a2 ; start of save frame array
; Label the columns ...
pea label(pc)
jsr _printf
addq.l #4,sp
bra.s 7$ ; jump in ...
; Loop through the captured size/task/address items. First, we
; select the format string.
5$: lea afmt(pc),a0 ; AllocMem format
tst.l 0(a2) ; allocation?
beq.s 6$ ; yes
lea ffmt(pc),a0 ; FreeMem format
6$: move.l 4(a2),-(sp) ; size
move.l 12(a2),-(sp) ; address
move.l 8(a2),-(sp) ; task ID
move.l a0,-(sp) ; format string
jsr _printf
lea 16(sp),sp
lea 16(a2),a2 ; advance array pointer
7$: dbra d2,5$ ; loop back
bra 1$
; Restore the library functions and exit ...
10$: bsr UnZap ; unpatch the entries
movea.l Save1,a1 ; buffer
move.l #MAXCNT*32,d0 ; total length
CALLSYS FreeMem
; Close the DOS library
CloseDOS:
movea.l d6,a1
CALLSYS CloseLibrary
Exit:
lea STACKBUF(sp),sp
rts
; Zap the EXEC library AllocMem and FreeMem functions ...
Zap: CALLSYS Disable ; no interruptions, please
move.w #_LVOAllocMem,a0 ; offset
movea.l a6,a1 ; library
move.l #AllocChk,d0 ; new (monitor) function
CALLSYS SetFunction
move.l d0,AllocFun ; save original value
move.w #_LVOFreeMem,a0
movea.l a6,a1
move.l #FreeChk,d0 ; monitor function
CALLSYS SetFunction
move.l d0,FreeFun
CALLSYS Enable
rts
; Restore the library entry points ...
UnZap: CALLSYS Disable
move.w #_LVOAllocMem,a0
movea.l a6,a1
move.l AllocFun,d0
CALLSYS SetFunction
move.w #_LVOFreeMem,a0
movea.l a6,a1
move.l FreeFun,d0
CALLSYS SetFunction
CALLSYS Enable
rts
; Static storage area ...
_stdout dc.l 0
_DOSBase dc.l 0
AllocFun dc.l 0 ; real AllocMem function
FreeFun dc.l 0 ; real FreeMem
Buffer dc.l 0 ; current buffer
Save1 dc.l 0 ; first buffer
Save2 dc.l 0 ; second buffer
label dc.b ' AllocMem FreeMem ',10
dc.b 'Task ID Addr Size Addr Size',10,0
afmt dc.b '%6lx: %6lx %4ld ',10,0
ffmt dc.b '%6lx: %6lx %4ld',10,0
DOSlib dc.b 'dos.library',0
CNOP 0,2
; AllocMem monitor function. This code will be executed by
; any function that calls AllocMem.
AllocChk:
movem.l d2/a2,-(sp)
movem.l d0/d1,-(sp)
; Disable interrupts while we check where to put the data ...
CALLSYS Disable
movea.l Buffer,a2 ; current buffer
cmpi.l #MAXCNT-1,(a2) ; count too big?
bcs.s 1$ ; no
clr.l (a2) ; reset
1$: move.l (a2),d2 ; count
lsl.l #4,d2 ; scale for 16 bytes
addq.l #1,(a2) ; increment count
lea 16(a2),a2 ; first save frame
CALLSYS Enable
; See who asked for it ...
suba.l a1,a1 ; see
CALLSYS FindTask
movea.l d0,a0
movem.l (sp)+,d0/d1 ; restore size and attributes
; Special (conditional) code to trap certain references ...
IFD SPECIAL
cmp.l #20,d0 ; 20 bytes?
bne.s 2$ ; no
trap #11 ; gotcha!
2$:
ENDC
lea 0(a2,d2.l),a2 ; start of frame
clr.l (a2)+ ; clear flag
move.l d0,(a2)+ ; save size
move.l a0,(a2)+ ; save task
movea.l AllocFun,a0
jsr (a0) ; call AllocMem
move.l d0,(a2) ; save address
movem.l (sp)+,d2/a2
rts
; Monitor FreeMem activity ...
FreeChk:
movem.l d2/a2,-(sp)
movem.l d0/a1,-(sp) ; save size and address
CALLSYS Disable
movea.l Buffer,a2 ; buffer area
cmpi.l #MAXCNT-1,(a2) ; count too big?
bcs.s 1$ ; no
clr.l (a2) ; reset it
1$: move.l (a2),d2 ; current item count
lsl.l #4,d2 ; scale for 16 bytes
addq.l #1,(a2) ; increment count
lea 16(a2),a2 ; first save frame
CALLSYS Enable
; See who asked for it ...
suba.l a1,a1
CALLSYS FindTask
movea.l d0,a0 ; requesting task
movem.l (sp)+,d0/a1
lea 0(a2,d2.l),a2 ; start of frame
move.l #-1,(a2)+ ; set flag
move.l d0,(a2)+ ; save size
move.l a0,(a2)+ ; save task
move.l a1,(a2) ; save address
movea.l FreeFun,a0
jsr (a0) ; call FreeMem
movem.l (sp)+,d2/a2
rts
END